package route

import (
	"bufio"
	"fmt"
	"net"
	"net/http"
	"os/exec"
	"regexp"

	"github.com/gin-gonic/gin"
)

var (
	ipRegex     = `^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
	domainRegex = `^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$`
)

// ValidateAddress 验证地址是否为合法的IP或域名，并返回解析后的IP地址
func ValidateAddress(address string) (string, error) {
	ipValid := regexp.MustCompile(ipRegex).MatchString(address)
	domainValid := regexp.MustCompile(domainRegex).MatchString(address)

	if !ipValid && !domainValid {
		return "", fmt.Errorf("invalid IP address or domain name")
	}

	if domainValid {
		ips, err := net.LookupIP(address)
		if err != nil {
			return "", fmt.Errorf("domain resolution failed")
		}
		return ips[0].String(), nil
	}

	return address, nil
}

func PingHandler(c *gin.Context) {
	dest := c.DefaultQuery("dest", "8.8.8.8")
	count := c.DefaultQuery("count", "4")

	// 使用公共函数验证地址
	validatedDest, err := ValidateAddress(dest)
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		return
	}

	// 设置响应头为流式输出
	c.Header("Content-Type", "text/event-stream")
	c.Header("Cache-Control", "no-cache")
	c.Header("Connection", "keep-alive")

	// 创建ping命令
	cmd := exec.Command("ping", "-c", count, validatedDest)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if err := cmd.Start(); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 实时读取输出并发送到客户端
	scanner := bufio.NewScanner(stdout)
	for scanner.Scan() {
		line := scanner.Text()
		fmt.Fprintf(c.Writer, "data: %s\n\n", line)
		c.Writer.Flush()
	}

	if err := cmd.Wait(); err != nil {
		fmt.Fprintf(c.Writer, "data: Error: %s\n\n", err.Error())
		c.Writer.Flush()
	}
}
